[Protocol] Add support for additional properties#407
Conversation
Package Size
React Native file breakdown
Android file breakdown
Measured from the PR base SHA and PR head SHA. The file breakdown shows uncompressed sizes within each package artifact, so individual files do not sum to the compressed artifact total. This comment reports package artifact sizes only; it is not a final app binary-size report. |
5d00641 to
7d209cf
Compare
7d209cf to
dec51dd
Compare
kieran-osgood-shopify
left a comment
There was a problem hiding this comment.
Everything looks good to me
This has me thinking about whether we're approaching the point we might want to consider a fork of quicktype for our purposes, or even some patch-package style changes so we dont have a total fork, to add some flag driven behaviour for us
It might wind up more maintainable than our script which relies on so much string.replace if we can insert some of the behaviour we are inserting here
0a835e5 to
a56fdd7
Compare
Yeah @kieran-osgood-shopify, this is what @westeezy was considering too. I think it's a nice idea to keep the generation logic encapsulated for our purposes and written in a way we know and like. |
What changes are you making?
This preserves untyped protocol extension properties across generated TypeScript, Swift, and Kotlin models.
What is wrong with the current state?
UCP schemas intentionally allow extension fields through open objects and map-like schemas. The current generated clients do not handle that consistently: Swift and Kotlin decode typed model fields but drop unknown object members, while TypeScript had map-like extension data represented as generated named interfaces such as
Signals. That makes current spec fields look more permanent than they are and means future extension keys can disappear or require generator changes when the spec shape changes.There is also a collision risk when unknown fields are re-encoded. If an extension map contains a key that matches a typed field, the typed field should remain authoritative.
What this fixes
The model generator now derives extension handling from the schema instead of from spec-specific names:
additionalPropertiesbucket in Swift and KotlinpropertyNamesplusadditionalPropertiesbecome native untyped maps in all languagesLanguage implications
TypeScript
Open generated models expose unknown fields through
additionalProperties, matching Swift and Kotlin. Map-like fields are still emitted inline as{ [key: string]: any }. For example,checkout.signalsis no longer a generatedSignalsinterface.Swift
Open generated models expose unknown fields as
additionalProperties: [String: JSONAny]. Map-like fields such assignalsare[String: JSONAny]?.Kotlin
Open generated models expose unknown fields as
additionalProperties: Map<String, JsonElement>. Map-like fields such assignalsareJsonObject?.